package cn.edu.sgu.www.mhxysy.service.xingshi.impl;

import cn.edu.sgu.www.mhxysy.consts.CustomMessages;
import cn.edu.sgu.www.mhxysy.dto.xingshi.XingshiFulingDTO;
import cn.edu.sgu.www.mhxysy.entity.xingshi.XingshiXianghunCategory;
import cn.edu.sgu.www.mhxysy.entity.xingshi.Xingshi;
import cn.edu.sgu.www.mhxysy.entity.xingshi.XingshiFuling;
import cn.edu.sgu.www.mhxysy.entity.xingshi.XingshiXianghun;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.mapper.xingshi.XingshiXianghunCategoryMapper;
import cn.edu.sgu.www.mhxysy.mapper.xingshi.XingshiFulingMapper;
import cn.edu.sgu.www.mhxysy.mapper.xingshi.XingshiMapper;
import cn.edu.sgu.www.mhxysy.mapper.xingshi.XingshiXianghunMapper;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.xingshi.XingshiFulingService;
import cn.edu.sgu.www.mhxysy.util.ObjectUtils;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import cn.edu.sgu.www.mhxysy.vo.except.AttributeVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class XingshiFulingServiceImpl implements XingshiFulingService {

	private final XingshiMapper xingshiMapper;
	private final XingshiXianghunCategoryMapper xingshiXianghunCategoryMapper;
	private final XingshiFulingMapper xingshiFulingMapper;
	private final XingshiXianghunMapper xingshiXianghunMapper;

	@Autowired
	public XingshiFulingServiceImpl(
			XingshiMapper xingshiMapper,
			XingshiXianghunCategoryMapper xingshiXianghunCategoryMapper,
			XingshiFulingMapper xingshiFulingMapper,
			XingshiXianghunMapper xingshiXianghunMapper) {
		this.xingshiMapper = xingshiMapper;
		this.xingshiXianghunCategoryMapper = xingshiXianghunCategoryMapper;
		this.xingshiFulingMapper = xingshiFulingMapper;
		this.xingshiXianghunMapper = xingshiXianghunMapper;
	}

	@Override
	public void insert(XingshiFulingDTO xingshiFulingDTO) {
		// 获取星石id
		String xingshiId = xingshiFulingDTO.getXingshiId();
		// 查询星石信息
		Xingshi xingshi = xingshiMapper.selectById(xingshiId);

		int size;

		if (xingshi.getGrade() == 10) {
			size = 3;
		} else if (xingshi.getGrade() >= 8) {
			size = 2;
		} else if (xingshi.getGrade() >= 5) {
			size = 1;
		} else {
			size = 0;
		}

		QueryWrapper<XingshiFuling> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("xingshi_id", xingshiId);

		List<XingshiFuling> list = xingshiFulingMapper.selectList(queryWrapper);

		if (list.size() >= size) {
			throw new GlobalException(ResponseCode.CONFLICT, "星石的附灵次数已达上限：" + size + "次");
		}

		// 添加星石附灵属性
		XingshiFuling xingshiFuling = toEntity(xingshiFulingDTO);
		
		xingshiFuling.setId(xingshiFuling.uuid());

		xingshiFulingMapper.insert(xingshiFuling);

		// 判断是否激活了相魂属性
		list.add(xingshiFuling);

		if (list.size() == 3) {
			// 创建一个map保存属性和个数
			Map<Integer, Integer> countMap = new HashMap<>();

			for (XingshiFuling fuling : list) {
				Integer propertyId = fuling.getPropertyId();

				if (countMap.containsKey(propertyId)) {
					Integer count = countMap.get(propertyId);

					countMap.put(propertyId, count + 1);
				} else {
					countMap.put(propertyId, 1);
				}
			}

			// 查询星石相魂属性类型，依次匹配
			List<XingshiXianghunCategory> xingshiXianghunCategoryList = xingshiXianghunCategoryMapper.selectList(null);

			xingshiXianghunCategoryList.forEach(new Consumer<XingshiXianghunCategory>() {
				@Override
				public void accept(XingshiXianghunCategory xingshiXianghunCategory) {
					Integer propertyId = xingshiXianghunCategory.getPropertyId();

					if (xingshiXianghunCategory.getQuantity().equals(countMap.get(propertyId))) {
						Integer xianghunId = xingshiXianghunCategory.getId();

						// 通过星石ID查询星石相魂属性
						QueryWrapper<XingshiXianghun> queryWrapper = new QueryWrapper<>();

						queryWrapper.eq("xingshi_id", xingshiId);

						XingshiXianghun dbResult = xingshiXianghunMapper.selectOne(queryWrapper);

						// 星石没有相魂则添加，否则修改相魂ID
						if (dbResult == null) {
							XingshiXianghun xingshiXianghun = new XingshiXianghun();

							xingshiXianghun.setId(xingshiXianghun.uuid());
							xingshiXianghun.setXianghunId(xianghunId);
							xingshiXianghun.setXingshiId(xingshiId);

							xingshiXianghunMapper.insert(xingshiXianghun);
						} else {
							dbResult.setXianghunId(xianghunId);

							xingshiXianghunMapper.updateById(dbResult);
						}
					}
				}
			});
		}
	}

	@Override
	public void deleteById(String id) {
		xingshiFulingMapper.deleteById(id);
	}

	@Override
	public void updateById(XingshiFulingDTO xingshiFulingDTO) {
		ObjectUtils.requireNonNull(xingshiFulingDTO.getId(), CustomMessages.ID_NOT_NULL);

		// 修改星石附灵属性
		XingshiFuling xingshiFuling = toEntity(xingshiFulingDTO);

		xingshiFulingMapper.updateById(xingshiFuling);

		// 得到星石ID
		String xingshiId = xingshiFulingDTO.getXingshiId();

		// 查询附灵属性
		QueryWrapper<XingshiFuling> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("xingshi_id", xingshiId);

		List<XingshiFuling> list = xingshiFulingMapper.selectList(queryWrapper);

		if (list.size() == 3) {
			// 创建一个map保存属性和个数
			Map<Integer, Integer> countMap = new HashMap<>();

			for (XingshiFuling fuling : list) {
				Integer propertyId = fuling.getPropertyId();

				if (countMap.containsKey(propertyId)) {
					Integer count = countMap.get(propertyId);

					countMap.put(propertyId, count + 1);
				} else {
					countMap.put(propertyId, 1);
				}
			}

			// 查询星石相魂属性类型，依次匹配
			List<XingshiXianghunCategory> xingshiXianghunCategoryList = xingshiXianghunCategoryMapper.selectList(null);

			xingshiXianghunCategoryList.forEach(new Consumer<XingshiXianghunCategory>() {
				@Override
				public void accept(XingshiXianghunCategory xingshiXianghunCategory) {
					Integer propertyId = xingshiXianghunCategory.getPropertyId();

					if (xingshiXianghunCategory.getQuantity().equals(countMap.get(propertyId))) {
						Integer xianghunId = xingshiXianghunCategory.getId();

						// 通过星石ID查询星石相魂属性
						QueryWrapper<XingshiXianghun> queryWrapper = new QueryWrapper<>();

						queryWrapper.eq("xingshi_id", xingshiId);

						XingshiXianghun dbResult = xingshiXianghunMapper.selectOne(queryWrapper);

						// 星石没有相魂则添加，否则修改相魂ID
						if (dbResult == null) {
							XingshiXianghun xingshiXianghun = new XingshiXianghun();

							xingshiXianghun.setId(xingshiXianghun.uuid());
							xingshiXianghun.setXianghunId(xianghunId);
							xingshiXianghun.setXingshiId(xingshiId);

							xingshiXianghunMapper.insert(xingshiXianghun);
						} else {
							dbResult.setXianghunId(xianghunId);

							xingshiXianghunMapper.updateById(dbResult);
						}
					}
				}
			});
		}
	}

	@Override
	public List<AttributeVO> selectAttributes(String xingshiId) {
		return xingshiFulingMapper.selectAttributes(xingshiId);
	}

	@Override
	public List<XingshiFuling> selectByXingshiId(String xingshiId) {
		if (StringUtils.isNullOrEmpty(xingshiId)) {
			return new ArrayList<>();
		}

		QueryWrapper<XingshiFuling> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("xingshi_id", xingshiId);

		return xingshiFulingMapper.selectList(queryWrapper);
	}

	private XingshiFuling toEntity(XingshiFulingDTO xingshiFulingDTO) {
		XingshiFuling xingshiFuling = new XingshiFuling();
		
		xingshiFuling.setId(xingshiFulingDTO.getId());
		xingshiFuling.setStep(xingshiFulingDTO.getStep());
		xingshiFuling.setXingshiId(xingshiFulingDTO.getXingshiId());
		xingshiFuling.setPropertyId(xingshiFulingDTO.getPropertyId());
		xingshiFuling.setPropertyValue(xingshiFulingDTO.getPropertyValue());
		
		return xingshiFuling;
	}

}